/*
 * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

/**
 * {@code java.lang.invoke} 包包含由 Java 核心类库和虚拟机直接提供的动态语言支持。
 *
 * <p>
 * 如 Java 虚拟机规范中所述，
 * 此包中的某些类型与虚拟机中的动态语言支持有特殊关系：
 * <ul>
 * <li>类 {@link java.lang.invoke.MethodHandle MethodHandle} 包含
 * <a href="MethodHandle.html#sigpoly">签名多态方法</a>，
 * 这些方法可以链接而不管其类型描述符如何。
 * 通常，方法链接需要类型描述符的精确匹配。
 * </li>
 *
 * <li>JVM 字节码格式支持
 * 类 {@link java.lang.invoke.MethodHandle MethodHandle} 和 {@link java.lang.invoke.MethodType MethodType} 的立即常量。
 * </li>
 * </ul>
 *
 * <h1><a name="jvm_mods"></a>相关 Java 虚拟机变更摘要</h1>
 * 以下低级信息总结了 Java 虚拟机规范的相关部分。
 * 有关完整详细信息，请参阅该规范的当前版本。
 *
 * {@code invokedynamic} 指令的每次出现都称为<em>动态调用站点</em>。
 * <h2><a name="indyinsn"></a>{@code invokedynamic} 指令</h2>
 * 动态调用站点最初处于未链接状态。在此状态下，
 * 调用站点没有要调用的目标方法。
 * <p>
 * 在 JVM 可以执行动态调用站点（{@code invokedynamic} 指令）之前，
 * 调用站点必须首先被<em>链接</em>。
 * 链接是通过调用<em>引导方法</em>来完成的，
 * 该方法被给予调用站点的静态信息内容，
 * 并且必须产生一个 {@link java.lang.invoke.MethodHandle 方法句柄}，
 * 该方法句柄给出调用站点的行为。
 * <p>
 * 每个 {@code invokedynamic} 指令静态地将其自己的
 * 引导方法指定为常量池引用。
 * 常量池引用还指定调用站点的名称和类型描述符，
 * 就像 {@code invokevirtual} 和其他调用指令一样。
 * <p>
 * 链接从解析引导方法的常量池条目开始，
 * 并为动态调用站点的类型描述符解析 {@link java.lang.invoke.MethodType MethodType} 对象。
 * 此解析过程可能触发类加载。
 * 因此，如果类加载失败，它可能抛出错误。
 * 此错误成为动态调用站点执行的异常终止。
 * 链接不会触发类初始化。
 * <p>
 * 引导方法至少在三个值上被调用：
 * <ul>
 * <li>一个 {@code MethodHandles.Lookup}，发生动态调用站点的<em>调用者类</em>上的查找对象</li>
 * <li>一个 {@code String}，调用站点中提到的方法名称</li>
 * <li>一个 {@code MethodType}，调用的已解析类型描述符</li>
 * <li>可选地，从常量池中获取的 1 到 251 个额外静态参数</li>
 * </ul>
 * 调用就像通过 {@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke} 一样。
 * 返回的结果必须是 {@link java.lang.invoke.CallSite CallSite}（或子类）。
 * 调用站点目标的类型必须完全等于
 * 从动态调用站点的类型描述符派生并传递给引导方法的类型。
 * 然后调用站点永久链接到动态调用站点。
 * <p>
 * 如 JVM 规范中所记录的，动态调用站点链接产生的所有失败
 * 都由 {@link java.lang.BootstrapMethodError BootstrapMethodError} 报告，
 * 它作为动态调用站点执行的异常终止被抛出。
 * 如果发生这种情况，对于所有后续执行动态调用站点的尝试，
 * 都会抛出相同的错误。
 *
 * <h2>链接时机</h2>
 * 动态调用站点在其首次执行之前被链接。
 * 实现链接的引导方法调用发生在尝试首次执行的线程内。
 * <p>
 * 如果有多个这样的线程，引导方法可能在多个线程中并发调用。
 * 因此，访问全局应用程序数据的引导方法必须采取通常的预防措施来防止竞态条件。
 * 无论如何，每个 {@code invokedynamic} 指令要么未链接，
 * 要么链接到唯一的 {@code CallSite} 对象。
 * <p>
 * 在需要具有单独可变行为的动态调用站点的应用程序中，
 * 它们的引导方法应该为每个链接请求产生不同的
 * {@link java.lang.invoke.CallSite CallSite} 对象。
 * 或者，应用程序可以将单个 {@code CallSite} 对象链接到
 * 多个 {@code invokedynamic} 指令，在这种情况下，
 * 对目标方法的更改将在每个指令处变得可见。
 * <p>
 * 如果多个线程同时为单个动态调用站点执行引导方法，
 * JVM 必须选择一个 {@code CallSite} 对象并将其可见地安装到所有线程。
 * 任何其他引导方法调用都被允许完成，但它们的结果被忽略，
 * 它们的动态调用站点调用继续使用最初选择的目标对象。

 * <p style="font-size:smaller;">
 * <em>讨论：</em>
 * 这些规则不允许 JVM 复制动态调用站点，
 * 或发出"无因"引导方法调用。
 * 每个动态调用站点最多从未链接转换到链接一次，
 * 就在其首次调用之前。
 * 没有办法撤销已完成的引导方法调用的效果。
 *
 * <h2>引导方法的类型</h2>
 * 只要每个引导方法都能被 {@code MethodHandle.invoke} 正确调用，
 * 其详细类型是任意的。
 * 例如，第一个参数可以是 {@code Object} 而不是 {@code MethodHandles.Lookup}，
 * 返回类型也可以是 {@code Object} 而不是 {@code CallSite}。
 * （注意，堆栈参数的类型和数量限制了引导方法的合法种类，
 * 只能是适当类型的静态方法和 {@code CallSite} 子类的构造函数。）
 * <p>
 * 如果给定的 {@code invokedynamic} 指令未指定静态参数，
 * 指令的引导方法将在三个参数上被调用，
 * 传递指令的调用者类、名称和方法类型。
 * 如果 {@code invokedynamic} 指令指定一个或多个静态参数，
 * 这些值将作为额外参数传递给方法句柄。
 * （注意，由于任何方法的参数限制为 255 个，
 * 最多可以提供 251 个额外参数，因为引导方法句柄本身
 * 及其前三个参数也必须被堆栈。）
 * 引导方法将像通过 {@code MethodHandle.invoke}
 * 或 {@code invokeWithArguments} 一样被调用。（无法区分差异。）
 * <p>
 * {@code MethodHandle.invoke} 的正常参数转换规则适用于所有堆栈参数。
 * 例如，如果推送的值是原始类型，它可能通过装箱转换转换为引用。
 * 如果引导方法是可变参数方法（其修饰符位 {@code 0x0080} 被设置），
 * 那么这里指定的部分或全部参数可能被收集到尾随数组参数中。
 * （这不是特殊规则，而是 {@code CONSTANT_MethodHandle} 常量、
 * 可变参数方法的修饰符位和 {@link java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector} 转换之间交互的有用结果。）
 * <p>
 * 根据这些规则，以下是合法引导方法声明的示例，
 * 给定各种额外参数数量 {@code N}。
 * 第一行（标记为 {@code *}）适用于任意数量的额外参数。
 * <table border=1 cellpadding=5 summary="静态参数类型">
 * <tr><th>N</th><th>示例引导方法</th></tr>
 * <tr><td>*</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)</code></td></tr>
 * <tr><td>*</td><td><code>CallSite bootstrap(Object... args)</code></td></tr>
 * <tr><td>*</td><td><code>CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)</code></td></tr>
 * <tr><td>0</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type)</code></td></tr>
 * <tr><td>0</td><td><code>CallSite bootstrap(Lookup caller, Object... nameAndType)</code></td></tr>
 * <tr><td>1</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)</code></td></tr>
 * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)</code></td></tr>
 * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)</code></td></tr>
 * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)</code></td></tr>
 * </table>
 * 最后一个示例假设额外参数分别是
 * {@code CONSTANT_String} 和 {@code CONSTANT_Integer} 类型。
 * 倒数第二个示例假设所有额外参数都是
 * {@code CONSTANT_String} 类型。
 * 其他示例适用于所有类型的额外参数。
 * <p>
 * 如上所述，引导方法的实际方法类型可以变化。
 * 例如，如果 {@code CONSTANT_InvokeDynamic} 条目中
 * 相应常量的类型是 {@code MethodHandle}，
 * 那么第四个参数可以是 {@code MethodHandle}。
 * 在这种情况下，{@code MethodHandle.invoke} 调用将额外的方法句柄
 * 常量作为 {@code Object} 传递，但 {@code MethodHandle.invoke}
 * 的类型匹配机制将在调用引导方法之前将引用转换回 {@code MethodHandle}。
 * （如果通过错误生成的代码传递字符串常量，那么该转换将失败，
 * 导致 {@code BootstrapMethodError}。）
 * <p>
 * 注意，作为上述规则的结果，如果原始参数可以由常量池条目表示，
 * 引导方法可以接受原始参数。
 * 但是，{@code boolean}、{@code byte}、{@code short} 或 {@code char}
 * 类型的参数不能为引导方法创建，因为这些常量不能直接
 * 在常量池中表示，引导方法的调用将不会
 * 执行必要的窄化原始转换。
 * <p>
 * 额外的引导方法参数旨在允许语言实现者
 * 安全且紧凑地编码元数据。
 * 原则上，名称和额外参数是冗余的，
 * 因为每个调用站点都可以给定自己唯一的引导方法。
 * 这种做法可能会产生大型类文件和常量池。
 *
 * @author John Rose, JSR 292 EG
 * @since 1.7
 */

package java.lang.invoke;
